import 'dart:math' as math;

import 'package:flutter/material.dart';

import '../decorate/decorate.dart';

/// $LoadingLineThinSpinFadeLoader.
class $LoadingLineThinSpinFadeLoader extends StatefulWidget {
  const $LoadingLineThinSpinFadeLoader({Key? key}) : super(key: key);

  @override
  State<$LoadingLineThinSpinFadeLoader> createState() => _$LoadingLineThinSpinFadeLoaderState();
}

class _$LoadingLineThinSpinFadeLoaderState extends State<$LoadingLineThinSpinFadeLoader> with TickerProviderStateMixin {
  late AnimationController controller;
  late Animation<int> animation;

  @override
  void initState() {
    controller = AnimationController(value: 0.0, duration: const Duration(milliseconds: 800), vsync: this);
    animation = IntTween(begin: 0, end: 11).animate(controller);

    controller.repeat();
    super.initState();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final $LoadingDecorateData decorateData = $LoadingDecorateContext.of(context)!.decorateData;
    return AnimatedBuilder(
      animation: animation,
      builder: (BuildContext context, Widget? child) {
        final Matrix4 transform = Matrix4.rotationZ(animation.value * math.pi / 6);
        return Transform(
          transform: transform,
          alignment: Alignment.center,
          child: child,
        );
      },
      child: CustomPaint(
        painter: $LoadingSpinnerPainter(color: decorateData.colors.elementAt(0), strokeWidth: decorateData.strokeWidth),
      ),
    );
  }
}

class $LoadingSpinnerPainter extends CustomPainter {
  $LoadingSpinnerPainter({
    required this.color,
    this.strokeWidth,
  })  : _paint = Paint()
          ..strokeWidth = strokeWidth ?? 2.0
          ..strokeCap = StrokeCap.round
          ..style = PaintingStyle.stroke,
        super();

  final double? strokeWidth;
  final Color color;
  final Paint _paint;

  @override
  void paint(Canvas canvas, Size size) {
    final double canvasWidth = size.width;
    final double canvasHeight = size.height;
    canvas.translate(canvasWidth / 2, canvasHeight / 2);
    for (int i = 0; i < 12; i++) {
      _paint.color = color.withOpacity(1 - 0.75 / 12 * i);
      canvas
        ..rotate(math.pi / 6)
        ..drawLine(
          Offset(0, canvasHeight * .28),
          Offset(0, canvasHeight * .5),
          _paint,
        );
    }
  }

  @override
  bool shouldRepaint($LoadingSpinnerPainter oldDelegate) => false;

  @override
  bool shouldRebuildSemantics($LoadingSpinnerPainter oldDelegate) => false;
}
